package com.yufubao.service.service.popularize.authorization.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yufubao.framework.constant.BeesConstant;
import com.yufubao.framework.enums.CommonExceptionEnum;
import com.yufubao.framework.exception.BaseException;
import com.yufubao.framework.result.PageUtils;
import com.yufubao.framework.util.CopyBean;
import com.yufubao.framework.util.MyCollUtil;
import com.yufubao.framework.util.page.Query;
import com.yufubao.model.dto.management.sys.SysBeesDelDto;
import com.yufubao.model.dto.popularize.authorization.BeesInfoDto;
import com.yufubao.model.pojo.management.authorization.ManagerEntity;
import com.yufubao.model.pojo.popularize.authorization.BeesInfoEntity;
import com.yufubao.model.vo.management.sys.SysBeesInfoVo;
import com.yufubao.service.mapper.popularize.authorization.BeesInfoDao;
import com.yufubao.service.service.management.authorization.ManagerService;
import com.yufubao.service.service.popularize.authorization.BeesInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.yufubao.framework.constant.ManagerStatus.ADMIN;
import static com.yufubao.framework.util.MapParamsUtil.getKey;
import static com.yufubao.framework.util.MapParamsUtil.getStatus;


@Service("beesInfoService")
public class BeesInfoServiceImpl extends ServiceImpl<BeesInfoDao, BeesInfoEntity> implements BeesInfoService {
    @Autowired
    private ManagerService managerService;

    /**
     * @param params
     * @return com.yufubao.framework.result.PageUtils
     * @description 分页查询小蜜蜂人员信息
     * @author zhangyiheng
     * @date 2024/9/16 14:47
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        String key = getKey(params);

        String status = getStatus(params);

        LambdaQueryWrapper<BeesInfoEntity> wrapper = Wrappers.<BeesInfoEntity>lambdaQuery()
                .like(StrUtil.isNotBlank(key), BeesInfoEntity::getNickname, key)
                .or().eq(StrUtil.isNotBlank(key), BeesInfoEntity::getPhone, key);

        if (StrUtil.isNotBlank(status)) {
            switch (status) {
                case BeesConstant.OPEN:
                    wrapper.and(wq -> wq.eq(BeesInfoEntity::getStatus, BeesConstant.OPEN));
                    break;
                case BeesConstant.STOP:
                    wrapper.and(wq -> wq.eq(BeesInfoEntity::getStatus, BeesConstant.STOP));
                    break;
                default:
                    break;
            }
        }

        long managerId = StpUtil.getLoginIdAsLong();
        //admin查询所有
        if (!Objects.equals(managerId, ADMIN)) {
            wrapper.eq(BeesInfoEntity::getManagerId, managerId);
        }

        IPage<BeesInfoEntity> page = this.page(
                new Query<BeesInfoEntity>().getPage(params),
                wrapper
        );

        List<BeesInfoEntity> records = page.getRecords();

        //查询代理人名称
        List<SysBeesInfoVo> vos = new ArrayList<>();
        if (MyCollUtil.isNotEmpty(records)) {
            vos = records.stream().map(po -> {
                SysBeesInfoVo sysBeesInfoVo = CopyBean.copyBean(po, SysBeesInfoVo.class);

                sysBeesInfoVo.setManagerName(Optional.ofNullable(managerService.getById(po.getManagerId()).getRealName()).orElse(""));
                return sysBeesInfoVo;
            }).collect(Collectors.toList());

            IPage<SysBeesInfoVo> pageVo = new Page<>();
            pageVo.setTotal(page.getTotal());
            pageVo.setRecords(vos);
            pageVo.setPages(page.getPages());
            pageVo.setSize(page.getSize());
            pageVo.setCurrent(page.getCurrent());

            return new PageUtils(pageVo);
        }

        return null;
    }


    /**
     * @param dto
     * @return void
     * @description 推广人/小蜜蜂人员表保存
     * @author zhangyiheng
     * @date 2024/9/16 15:02
     */
    @Override
    @Transactional
    public void saveInfo(BeesInfoDto dto) {

        //判断是否重复注册
        if (accountExist(dto.getAccount())) {
            throw new BaseException(CommonExceptionEnum.ZHMYCZ);
        }
        if (phoneExist(dto.getPhone())) {
            throw new BaseException(CommonExceptionEnum.SJHYCZ);
        }

        BeesInfoEntity bees = CopyBean.copyBean(dto, BeesInfoEntity.class);

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        bees.setPassword(encoder.encode(bees.getPassword()));
        //如果没有代理人id或代理人id不存在则分配给admin
        if (!StpUtil.isLogin()) {

            if (Objects.isNull(bees.getManagerId())) {
                bees.setManagerId(ADMIN);
                //修改总小蜜蜂人数
                updateTotalBess(ADMIN);
            } else {
                long count = managerService.count(Wrappers.<ManagerEntity>lambdaQuery()
                        .eq(ManagerEntity::getManagerId, bees.getManagerId()));
                if (Objects.equals(count, 0)) {
                    bees.setManagerId(ADMIN);
                    //修改总小蜜蜂人数
                    updateTotalBess(ADMIN);
                }
                bees.setManagerId(bees.getManagerId());
                //修改总小蜜蜂人数
                updateTotalBess(bees.getManagerId());
            }

            //保存
            this.save(bees);
        } else {
            //保证代理
            ManagerEntity manager = StpUtil.getSession().getModel(SaSession.USER, ManagerEntity.class);
            bees.setManagerId(manager.getManagerId());

            //修改总小蜜蜂人数
            managerService.update(Wrappers.<ManagerEntity>lambdaUpdate()
                    .set(ManagerEntity::getTotalBees, Optional.ofNullable(manager.getTotalBees()).orElse(0) + 1)
                    .eq(ManagerEntity::getManagerId, manager.getManagerId()));
            //保存
            this.save(bees);
        }

    }

    //修改admin小蜜蜂人数
    private void updateTotalBess(long managerId) {
        managerService.update(Wrappers.<ManagerEntity>lambdaUpdate()
                .set(ManagerEntity::getTotalLower, Optional.ofNullable(managerService.getById(managerId).getTotalBees()).orElse(0) + 1)
                .eq(ManagerEntity::getManagerId, managerId));
    }

    //校验手机号是否重复
    private boolean phoneExist(String phone) {
        long count = this.count(Wrappers.<BeesInfoEntity>lambdaQuery()
                .eq(BeesInfoEntity::getPhone, phone));
        return count > 0L;
    }

    //校验账号是否重复
    private boolean accountExist(String account) {
        long count = this.count(Wrappers.<BeesInfoEntity>lambdaQuery()
                .eq(BeesInfoEntity::getAccount, account));
        return count > 0L;
    }

    /**
     * @param beesId
     * @param status
     * @return void
     * @description 推广人/小蜜蜂人员表修改状态
     * @author zhangyiheng
     * @date 2024/9/16 15:30
     */
    @Override
    @Transactional
    public void updateStatus(Long beesId, String status) {
        //判断代理人关系
        BeesInfoEntity bees = this.getById(beesId);
        if (Objects.isNull(bees)) {
            throw new BaseException(CommonExceptionEnum.NOT_FOUND);
        }

        if (!Objects.equals(StpUtil.getLoginIdAsLong(), bees.getManagerId())) {
            throw new BaseException(CommonExceptionEnum.NOT_PERMISSION);
        }

        this.update(Wrappers.<BeesInfoEntity>lambdaUpdate()
                .set(BeesInfoEntity::getStatus, status)
                .eq(BeesInfoEntity::getBeesId, beesId));

    }

    /**
     * @param dto
     * @return void
     * @description 单个删除/批量删除
     * @author zhangyiheng
     * @date 2024/9/16 16:36
     */
    @Override
    @Transactional
    public void deleteByIds(List<SysBeesDelDto> dto) {
        ManagerEntity manager = StpUtil.getSession().getModel(SaSession.USER, ManagerEntity.class);
        if (MyCollUtil.isNotEmpty(dto)) {
            for (SysBeesDelDto d : dto) {
                if (Objects.equals(d.getManagerId(), manager.getManagerId())) {
                    if (Objects.equals(d.getStatus(), BeesConstant.OPEN)) {
                        throw new BaseException(CommonExceptionEnum.XMFSQYYZT_BNSC);
                    }
                    //TODO 设计提现、金额等业务是否需要校验？

                    //删除
                    this.removeById(d.getBeesId());
                } else {
                    throw new BaseException(CommonExceptionEnum.NOT_PERMISSION);
                }
            }
            //修改代理人小蜜蜂数量
            managerService.update(Wrappers.<ManagerEntity>lambdaUpdate()
                    .set(ManagerEntity::getTotalBees, manager.getTotalBees() - dto.size() + 1)
                    .eq(ManagerEntity::getManagerId, manager.getManagerId()));
        }

    }
}